//########################################################################
//## (C) by Edwin Vriethoff under Microsoft Reciprocal License (Ms-RL)  ##
//## See http://www.codeplex.com/SPUserPoll/license for full license    ##
//##                                                                    ##
//## http://edwin.vriethoff.net http://www.codeplex.com/SPUserPoll/     ##
//########################################################################

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Data;
using System.Web.UI.WebControls;

namespace SPUserPoll.Data.Components
{
    public class AnswersList
    {
        const string c_AnswersListName = "SPUserPoll answers";
        const string c_AnswersListDesc = "Contains the possible answers for the polls";
        const string c_QueryItems = "<Where><IsNotNull><FieldRef Name='Title' /></IsNotNull></Where>";

        /// <summary>
        /// Returns the answerslist name for the specified poll
        /// </summary>
        /// <returns></returns>
        public static string GetAnswersListName()
        {
            return c_AnswersListName;
        }

        /// <summary>
        /// Check if the folder for the poll exist
        /// </summary>
        /// <param name="pollName"></param>
        /// <returns></returns>
        public bool AnswerFolderExist(string pollName)
        {
            SPList answerList = GetListForPoll(SPContext.Current.Web);
            foreach (SPListItem folder in answerList.Folders)
            {
                if (folder.Name.ToLower() == pollName)
                {
                    //folder has been found
                    return true;
                }
            }

            //folder has not been found
            return false;

        }

        /// <summary>
        /// Returns the path for the answer folder
        /// </summary>
        /// <param name="pollID"></param>
        /// <returns></returns>
        public static string GetAnswerFolderPath(string pollID)
        {
            //Get the folder name
            string pollTitle = AdminList.GetPollTitle(pollID).ToLower();

            //get the list containing the folder
            AnswersList aList = new AnswersList();
            SPList answerList = aList.GetListForPoll(SPContext.Current.Web);
            foreach (SPListItem folder in answerList.Folders)
            {
                if (folder.Name.ToLower() == pollTitle)
                {
                    //return the url of the folder
                    return folder.Url;
                }
            }

            //the folder has not been found. Create it
            aList.RegisterPoll(SPContext.Current.Web, pollTitle, pollID);
            //return the newly created folder
            return GetAnswerFolderPath(pollID);
        }

        /// <summary>
        /// Get the answer folder
        /// </summary>
        /// <param name="web"></param>
        /// <param name="pollID"></param>
        /// <returns></returns>
        private SPFolder GetAnswerFolder(SPWeb web, string pollID)
        {
            //Get the folder name
            string pollTitle = AdminList.GetPollTitle(pollID).ToLower();

            //get the list containing the folder
            SPList answerList = GetListForPoll(web);
            foreach (SPListItem folder in answerList.Folders)
            {
                if (folder.Name.ToLower() == pollTitle)
                {
                    //return the url of the folder
                    return web.GetFolder(folder.UniqueId);
                }
            }

            //the folder has not been found. Create it
            RegisterPoll(web, pollTitle, pollID);
            //return the newly created folder
            return GetAnswerFolder(web, pollID);
        }

        /// <summary>
        /// Adds a folder for the poll
        /// </summary>
        /// <param name="pollSite"></param>
        /// <param name="pollTitle"></param>
        /// <param name="pollID"></param>
        /// <returns></returns>
        public SPList RegisterPoll(SPWeb pollSite, string pollTitle, string pollID)
        {
            SPList answerList = GetListForPoll(pollSite);

            //Add the new poll folder
            try
            {
                answerList.ParentWeb.AllowUnsafeUpdates = true;
                SPListItem newFolder = answerList.Items.Add("", SPFileSystemObjectType.Folder, pollTitle);
                newFolder.Update();
            }
            finally
            {
                answerList.ParentWeb.AllowUnsafeUpdates = false;
            }
            return answerList;
        }
        
        /// <summary>
        /// Create a new answers list
        /// </summary>
        /// <param name="createAtWeb"></param>
        /// <returns></returns>
        private SPList CreateList(SPWeb createAtWeb)
        {
           SPSecurity.RunWithElevatedPrivileges(delegate()
           {

               //open the required poll list
               using (SPWeb web = new SPSite(createAtWeb.Site.RootWeb.Url).OpenWeb())
               {
                   try
                   {
                       web.AllowUnsafeUpdates = true;
                       string pollAnswersList = GetAnswersListName();
                       string pollAnswersDesc = c_AnswersListDesc;

                       //create the basic list
                       Guid newListGuid = web.Lists.Add(pollAnswersList, pollAnswersDesc, SPListTemplateType.GenericList);
                       SPList alterList = web.Lists[newListGuid];

                       //rename title column
                       alterList.Fields["Title"].Title = "Answer";
                       alterList.Fields["Title"].Update();

                       //add additional columns to it

                       //apply updates
                       alterList.Update();

                       //set view
                       SPView defaultView = alterList.DefaultView;
                       defaultView.ViewFields.DeleteAll();
                       defaultView.ViewFields.Add("Type");
                       defaultView.ViewFields.Add("LinkTitle");
                       //defaultView.ViewFields.Add("PollOrdering");
                       defaultView.Query = @"<OrderBy><FieldRef Name='Title' /></OrderBy>";
                       defaultView.Update();

                       //Add eventhandler registrations
                       alterList.EventReceivers.Add(SPEventReceiverType.ItemAdded, "SPUserPoll.Business.Components, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b504d4b6c1e1a6e5", "SPUserPoll.Business.Components.AnswerAndResponseEventHandler");
                       alterList.EventReceivers.Add(SPEventReceiverType.ItemUpdated, "SPUserPoll.Business.Components, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b504d4b6c1e1a6e5", "SPUserPoll.Business.Components.AnswerAndResponseEventHandler");
                       alterList.EventReceivers.Add(SPEventReceiverType.ItemDeleting, "SPUserPoll.Business.Components, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b504d4b6c1e1a6e5", "SPUserPoll.Business.Components.AnswerAndResponseEventHandler");
                       alterList.Update();           

                   }
                   finally
                   {
                       web.AllowUnsafeUpdates = false;
                   }
               };
           });
           
            //return the list
            return GetListForPoll(createAtWeb);
        }

        /// <summary>
        /// Are there answers in the list?
        /// </summary>
        /// <param name="pollID"></param>
        /// <returns></returns>
        public bool ContainsAnswers(string pollID)
        {
            try
            {
                bool containsAnswers = false;
                //Requires elevated rights on subsite to access the root site.
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    //open the required poll list
                    using (SPWeb web = new SPSite(SPContext.Current.Web.Site.RootWeb.Url).OpenWeb())
                    {

                        SPList answersList = GetListForPoll(web);

                        //Create the lookup query
                        SPQuery query = new SPQuery();
                        query.Query = c_QueryItems;
                        query.Folder = GetAnswerFolder(web, pollID);

                        if (answersList.GetItems(query).Count > 0)
                        {
                            containsAnswers = true;
                        }
                    }
                });

                return containsAnswers;
            }
            catch
            {
                //list could not be retrieved
                return false;
            }

        }

        /// <summary>
        /// Returns the poll answers
        /// </summary>
        /// <param name="pollID"></param>
        /// <returns></returns>
        public DataTable GetPollAnswers(string pollID)
        {
            DataTable items = null;
            
            //Requires elevated rights on subsite to access the datatable.
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {

                //open the required poll list
                using (SPWeb web = new SPSite(SPContext.Current.Web.Site.RootWeb.Url).OpenWeb())
                {

                    //get the main list
                    SPList answerList = GetListForPoll(web);

                    //Create the lookup query
                    SPQuery query = new SPQuery();
                    query.Query = c_QueryItems;
                    query.Folder = GetAnswerFolder(web, pollID);

                    items = answerList.GetItems(query).GetDataTable();
                   
                }
            });

            return items;
        }

        /// <summary>
        /// return listitems for each item in the answer list for the specified folder name
        /// </summary>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public List<ListItem> GetPollAnswerDropDownItems(string folderName)
        {
            List<ListItem> listItems = new List<ListItem>();

            //Get the pollID based on the foldername
            string pollID = AdminList.GetPollID(folderName, null);
            if (string.IsNullOrEmpty(pollID) == false)
            {
                SPListItemCollection items = GetPollAnswerListItems(pollID);
                foreach (SPListItem item in items)
                {
                    //add the id of each item
                    ListItem newListItem = new ListItem(item.Title.ToString(), item.ID.ToString());
                    listItems.Add(newListItem);
                }
            }
            return listItems;
        }

        /// <summary>
        /// Returns the poll answers
        /// </summary>
        /// <param name="pollID"></param>
        /// <returns></returns>
        public SPListItemCollection GetPollAnswerListItems(string pollID)
        {
            SPListItemCollection returnItems = null;

            //Requires elevated rights on subsite to access the datatable.
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {

                //open the required poll list
                using (SPWeb web = new SPSite(SPContext.Current.Web.Site.RootWeb.Url).OpenWeb())
                {

                    //get the main list
                    SPList answerList = GetListForPoll(web);

                    //Create the lookup query
                    SPQuery query = new SPQuery();
                    query.Query = c_QueryItems;
                    query.Folder = GetAnswerFolder(web, pollID);

                    returnItems = answerList.GetItems(query);
                }
            });

            return returnItems;
        }

        /// <summary>
        /// Get the poll list
        /// </summary>
        /// <param name="openFromWeb"></param>
        /// <param name="pollID"></param>
        /// <returns></returns>
        public SPList GetListForPoll(SPWeb openFromWeb)
        {
            //we recreate the webobject because sharepoint does not see newly created lists in the already openend web
            using (SPWeb web = new SPSite(openFromWeb.Site.RootWeb.Url).OpenWeb())
            {
                try
                {
                    //Check if the folder exist by accessing the list
                    SPList answerList = web.Lists[GetAnswersListName()];
                    
                    //Return the folder
                    return answerList;
                }
                catch (ArgumentException)
                {
                    
                    //recreate the answerlist
                    return CreateList(web);
                }
            }
        }
    }
}
